From bdcd090c17aebd8ffb964d98cd0984a3fc123a50 Mon Sep 17 00:00:00 2001 From: Debarshi Ray Date: Thu, 9 Nov 2017 07:48:26 +0100 Subject: [PATCH] CIE: Add "CIE L float" Some of these conversions will be leveraged by gegl:shadows-highlights which needs to go from "Y float" or "YaA float" to "CIE L float". The conversion from "RGBA float" was added to aid "YaA float" to "CIE L float" fishes. They go via: "YaA float" to "RaGaBaA float" "RaGaBaA float" to "RGBA float" "RGBA float" to "Y float" "Y float" to "CIE L float" A direct conversion from "YaA float" to "Y float" in simple C is hindered by the need to check every pixel's alpha value to avoid dividing by zero. The pipeline stalls make it lose out to the look-up table and SIMD based RGB conversions to unassociated alpha. However, we can trivially cut out the third step and still reduce some memory traffic. https://bugzilla.gnome.org/show_bug.cgi?id=790111 --- extensions/CIE.c | 138 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 138 insertions(+) diff --git a/extensions/CIE.c b/extensions/CIE.c index 60d480b..658fd2a 100644 --- a/extensions/CIE.c +++ b/extensions/CIE.c @@ -2,6 +2,7 @@ * Copyright (C) 2005, 2014 Øyvind Kolås. * Copyright (C) 2009, Martin Nordholts * Copyright (C) 2014, Elle Stone + * Copyright (C) 2017, Red Hat, Inc. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -591,6 +592,44 @@ cubef (float f) return f * f * f; } +static void +Yf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + long n = samples; + + while (n--) + { + float yr = src[0]; + float L = yr > LAB_EPSILON ? 116.0f * _cbrtf (yr) - 16 : LAB_KAPPA * yr; + + dst[0] = L; + + src++; + dst++; + } +} + +static void +Yaf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + long n = samples; + + while (n--) + { + float yr = src[0]; + float L = yr > LAB_EPSILON ? 116.0f * _cbrtf (yr) - 16 : LAB_KAPPA * yr; + + dst[0] = L; + + src += 2; + dst += 1; + } +} + static void Yaf_to_Laf (const Babl *conversion,float *src, float *dst, @@ -656,6 +695,36 @@ rgbf_to_Labf (const Babl *conversion,float *src, } } +static void +rgbaf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + const Babl *space = babl_conversion_get_source_space (conversion); + float m_1_0 = space->space.RGBtoXYZf[3] / D50_WHITE_REF_Y; + float m_1_1 = space->space.RGBtoXYZf[4] / D50_WHITE_REF_Y; + float m_1_2 = space->space.RGBtoXYZf[5] / D50_WHITE_REF_Y; + long n = samples; + + while (n--) + { + float r = src[0]; + float g = src[1]; + float b = src[2]; + + float yr = m_1_0 * r + m_1_1 * g + m_1_2 * b; + + float fy = yr > LAB_EPSILON ? _cbrtf (yr) : (LAB_KAPPA * yr + 16.0f) / 116.0f; + + float L = 116.0f * fy - 16.0f; + + dst[0] = L; + + src += 4; + dst += 1; + } +} + static void rgbaf_to_Labf (const Babl *conversion,float *src, float *dst, @@ -746,6 +815,38 @@ rgbaf_to_Labaf (const Babl *conversion,float *src, } } +static void +Labf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + long n = samples; + + while (n--) + { + dst[0] = src[0]; + + src += 3; + dst += 1; + } +} + +static void +Labaf_to_Lf (const Babl *conversion,float *src, + float *dst, + long samples) +{ + long n = samples; + + while (n--) + { + dst[0] = src[0]; + + src += 4; + dst += 1; + } +} + static void Labf_to_rgbf (const Babl *conversion,float *src, float *dst, @@ -1005,12 +1106,42 @@ conversions (void) "linear", Labaf_to_rgbaf, NULL ); + babl_conversion_new ( + babl_format ("Y float"), + babl_format ("CIE L float"), + "linear", Yf_to_Lf, + NULL + ); + babl_conversion_new ( + babl_format ("YA float"), + babl_format ("CIE L float"), + "linear", Yaf_to_Lf, + NULL + ); babl_conversion_new ( babl_format ("YA float"), babl_format ("CIE L alpha float"), "linear", Yaf_to_Laf, NULL ); + babl_conversion_new ( + babl_format ("RGBA float"), + babl_format ("CIE L float"), + "linear", rgbaf_to_Lf, + NULL + ); + babl_conversion_new ( + babl_format ("CIE Lab float"), + babl_format ("CIE L float"), + "linear", Labf_to_Lf, + NULL + ); + babl_conversion_new ( + babl_format ("CIE Lab alpha float"), + babl_format ("CIE L float"), + "linear", Labaf_to_Lf, + NULL + ); babl_conversion_new ( babl_model ("RGBA"), babl_model ("CIE LCH(ab)"), @@ -1109,6 +1240,13 @@ formats (void) babl_component ("A"), NULL); + babl_format_new ( + "name", "CIE L float", + babl_model ("CIE Lab"), + babl_type ("float"), + babl_component ("CIE L"), + NULL); + babl_format_new ( "name", "CIE L alpha float", babl_model ("CIE Lab alpha"), -- 2.30.2